/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       owned_adv_object.h

	$Header: /game/owned_adv_object.h $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "owned_adv_object.h"

#include <cassert>

#include "adventure_map.h"
#include "float_object.h"
#include "footprint.h"
#include "map_renderer.h"
#include "player.h"
#include "sized_int_types.h"
#include "streambuf_operators.h"

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::destroy()
{
	if (is_on_map() && m_owner >= 0)
		get_owner()->remove_object( this );

	t_stationary_adventure_object::destroy();
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::set_owner( int player_number )
{
	if ( player_number == m_owner )
		return;

	if (m_map!=NULL)
		m_map->record_set_owner_event( this, player_number );

	int old_owner = m_owner;

	if (is_on_map() && m_owner >= 0)
		get_owner()->remove_object( this );

	m_owner = player_number;

	if (is_on_map() && m_owner >= 0)
		get_owner()->add_object( this );

	setup_flag_color();
	on_owner_changed( m_owner, old_owner );

}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
bool t_owned_adv_object::write( std::streambuf& stream ) const
{
	put<t_int8>( stream, m_owner );
	return true;
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
bool t_owned_adv_object::read( std::streambuf&					 stream, 
							   t_qualified_adv_object_type const& type,
							   int								 version )
{
	set_owner( get<t_int8>( stream ) );
	return true;
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::initialize( t_adventure_map& map )
{
	// At this point the owner should NOT be set
	assert( m_owner < 0 );

	t_stationary_adventure_object::initialize( map );

	// Translate the player color into an owner number
	if ( m_player_color != k_player_gray )
	{
		// Note: it is acceptable to have things owned
		// by a non-playable position. We still don't
		// want them to lose their flag color, though.
		m_owner = map.get_or_add_player_number( m_player_color );

		assert( m_owner >= 0 );

		// m_player_color has now served its purpose and will no longer
		// be accessed
		m_player_color = k_player_gray;
	}

	if (m_owner >= 0)
		get_owner()->add_object( this );

	setup_flag_color();

	if ( m_owner >= 0 )
		on_owner_changed( m_owner, -1 );
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::place( t_adventure_map& map, t_adv_map_point const& point )
{
	t_stationary_adventure_object::place( map, point );

	if (m_owner >= 0)
		get_owner()->add_object( this );
	setup_flag_color();
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::setup_flag_color()
{
	if ( is_on_map() )
	{
		t_float_object floater( this );
		if ( m_owner >= 0 )
			set_flag_color( m_map->get_player( m_owner ).get_color() );
		else
			set_flag_color( k_player_gray );
	}
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
int t_owned_adv_object::get_scouting_range() const
{
	return m_scouting_range;
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
int t_owned_adv_object::compute_scouting_range() const
{
	t_map_point_2d const & footprint_size = get_footprint().get_size();

	int width;
	if ( footprint_size.row > footprint_size.column )
		width = footprint_size.row;
	else
		width = footprint_size.column;

	return width / 2 + 3;
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
void t_owned_adv_object::update_state()
{
	t_stationary_adventure_object::update_state();

	int new_scouting_range = compute_scouting_range();
	if ( new_scouting_range != m_scouting_range )
	{
		int old_scouting_range = m_scouting_range;
		m_scouting_range = new_scouting_range;

		on_scouting_range_changed( new_scouting_range, old_scouting_range );
	}
}

// -----------------------------------------------------------
// object owned by a player
// -----------------------------------------------------------
t_player_color t_owned_adv_object::get_player_color() const
{
	t_player * owner_ptr = get_owner();
	return owner_ptr != 0 ? owner_ptr->get_color() : m_player_color;
}
